package com.ysd.modules.app.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ysd.common.exception.RRException;
import com.ysd.common.utils.DateUtils;
import com.ysd.modules.app.dao.*;
import com.ysd.modules.app.entity.*;
import com.ysd.modules.app.service.TestPapersService;
import net.bytebuddy.implementation.bytecode.Throw;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

@Service
public class TestPapersServiceImpl extends ServiceImpl<TestPapersDao, TestPaper> implements TestPapersService {
    @Resource
    private TopicDao topicDao;
    @Resource
    private OptionsDao optionsDao;
    @Resource
    private PaperInfoDao paperInfoDao;
    @Resource
    private PracticeResultDao practiceResultDao;
    @Resource
    private StudentDao studentDao;
    @Resource
    private CoursesDao coursesDao;

    /**
     * 根据 课程和章节查找试卷信息(都是练习)
     *
     * @param courseId
     * @param chapterId
     * @return
     */
    @Override
    public List<TestPaper> getTestPapers(Integer courseId, Integer chapterId, Integer testMode) {
        if (courseId == null || courseId == 0) {
            throw new RRException("课程ID不能为空或者0");
        }
        QueryWrapper<TestPaper> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("course_id", courseId);
        queryWrapper.eq("test_mode", testMode);
        /**
         * 未做此业务,看是否需要
         */
        if (chapterId != null && chapterId != 0) {
            queryWrapper.eq("chapterId", chapterId);
        }
        List<TestPaper> testPaperList = baseMapper.selectList(queryWrapper);
        if (testPaperList != null && testPaperList.size() > 0) {
            for (int i = 0; i < testPaperList.size(); i++) {
                TestPaper testPaper = testPaperList.get(i);
                String createTime = testPaper.getCreateTime().substring(0, testPaper.getCreateTime().length() - 2);
                Date cd = DateUtils.stringToDate(createTime, DateUtils.DATE_TIME_PATTERN);
                /**
                 * 考试结束时间大于当前系统时间证明考试过期
                 */
                if (testPaper.getDuration() * 60 * 1000 < (new Date().getTime() - cd.getTime())) {
                    testPaper.setState("已过期");
                }
                /**
                 * 考试开始时间 大于 当前系统时间证明考试 未开始
                 */
                if (cd.getTime() > new Date().getTime()) {
                    testPaper.setState("未开始");
                }
                /**
                 * 当前系统时间 大于考试开始时间并且小于考试结束时间 则 考试中
                 */
                Calendar c1 = Calendar.getInstance();
                c1.setTime(cd);
                c1.add(Calendar.MINUTE, testPaper.getDuration());
                System.out.println(c1.getTime());
                if (cd.getTime() <= new Date().getTime() && new Date().getTime() <= c1.getTime().getTime()) {
                    testPaper.setState("考试中");
                }
            }
        }
        return testPaperList;
    }

    /**
     * 根据试卷id查询试卷题目
     *
     * @param pid
     * @return
     */
    @Override
    public List<TopicEntity> getTopicsByPid(Integer pid) {
        if (pid == null || pid == 0) {
            throw new RRException("试卷id不能为空或者0");
        }
        List<TopicEntity> topicList = topicDao.getTopicsByPid(pid);
        if (!topicList.isEmpty()) {
            for (int i = 0; i < topicList.size(); i++) {
                TopicEntity topicEntity = topicList.get(i);
                QueryWrapper<OptionsEntity> qw1 = new QueryWrapper<>();
                qw1.eq("topic_id", topicEntity.getId());
                List<OptionsEntity> optionsList = optionsDao.selectList(qw1);
                topicEntity.setOptionsList(optionsList);
            }
        }
        return topicList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public TestPaper insert(TestPaper testPaper) {
        int len = baseMapper.insertTestPaper(testPaper);
        if (len != 0) {
            List<TopicEntity> topicList = topicDao.getTopicsByCid(testPaper.getCourseId());
            if (topicList == null || topicList.size() == 0) {
                throw new RRException("该课程下没有试题!");
            }
            if (testPaper.getTopicNum() > topicList.size()) {
                for (int i = 0; i < topicList.size(); i++) {
                    TopicEntity topicEntity = topicList.get(i);
                    PaperInfo paperInfo = new PaperInfo();
                    paperInfo.setPaperId(testPaper.getId().intValue());
                    paperInfo.setTopicId(topicEntity.getId() + "");
                    int len1 = paperInfoDao.insert(paperInfo);
                    if (len1 == 0) {
                        throw new RRException("试卷生成失败");
                    }
                }
            } else {
                List<TopicEntity> list = getRandomListData(topicList, testPaper.getTopicNum());
                for (int i = 0; i < list.size(); i++) {
                    PaperInfo paperInfo = new PaperInfo();
                    paperInfo.setPaperId(testPaper.getId().intValue());
                    paperInfo.setTopicId(list.get(i).getId() + "");
                    int len1 = paperInfoDao.insert(paperInfo);
                    if (len1 == 0) {
                        throw new RRException("试卷生成失败");
                    }
                }
            }
        }
        return testPaper;
    }

    /**
     * 试卷详情
     *
     * @param pid
     * @return
     */
    @Override
    public Map<String, Object> getPaperDetails(Integer pid) {
        Map<String, Object> map = new HashMap<>();
        if (pid == null || pid == 0) {
            throw new RRException("试卷id不能为空或者0");
        }
        TestPaper testPaper = baseMapper.selectById(pid);
        if (testPaper == null) {
            throw new RRException("没有该试卷信息");
        }
        // 年份
        map.put("year", testPaper.getCreateTime().substring(0, 4) + "年");
        // 类型
        map.put("title", testPaper.getTitle());
        // 总分
        QueryWrapper<PaperInfo> paq = new QueryWrapper<>();
        paq.eq("paper_id", pid);
        List<PaperInfo> paperInfoList = paperInfoDao.selectList(paq);
        if (paperInfoList == null || paperInfoList.size() <= 0) {
            throw new RRException("该试卷没有题目");
        }
        double sum = 0;
        for (int i = 0; i < paperInfoList.size(); i++) {
            PaperInfo paperInfo = paperInfoList.get(i);
            TopicEntity topicEntity = topicDao.selectById(paperInfo.getTopicId());
            sum += topicEntity.getScore() == null ? 0 : topicEntity.getScore();
        }
        map.put("sum", sum);
        // 时长
        map.put("duration", testPaper.getDuration());
        // 做过人数
        QueryWrapper<PracticeResult> pr = new QueryWrapper<>();
        pr.eq("type", 1);
        pr.eq("target_id", pid);
        int count = practiceResultDao.selectCount(pr);
        map.put("count", count);
        // 评论
        map.put("comment", "0");
        return map;
    }

    /**
     * 每日一练-组卷
     *
     * @param courseId
     * @param topicNum
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public TestPaper addPaper(String title, Integer courseId, Integer topicNum, Integer stuId, Integer testMode) {
        TestPaper testPaper = new TestPaper();
        /**
         * 如果 testMode为2 则为每日一练
         *  每日一练不需要增加的操作，直接获取之前的testPaper
         */
        if (testMode == 2) {
            String nowDate = DateUtils.format(new Date());
            TestPaper testPaper1 = baseMapper.getTestPaperByDate(nowDate);
            if (testPaper1 != null) {
                return testPaper1;
            }
        }
        testPaper.setTitle(DateUtils.format(new Date(), DateUtils.DATE_PATTERN) + "-" + title);
        testPaper.setDuration(120);
        testPaper.setStatus(1);
        StudentEntity studentEntity = studentDao.selectById(stuId);
        if (studentEntity == null) {
            throw new RRException("没有该学生信息");
        }
        testPaper.setCreateId(stuId);
        testPaper.setCreateName(studentEntity.getName());
        testPaper.setCreateTime(DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN));
        testPaper.setTopicNum(topicNum);
        /**
         * 课程信息
         */
        CourseEntity courseEntity = coursesDao.selectById(courseId);
        if (courseEntity == null) {
            throw new RRException("没有找到该课程信息");
        }
        testPaper.setCourseId(courseId);
        testPaper.setCourseName(courseEntity.getName());
        testPaper.setType(1);
        testPaper.setTestMode(testMode);
        return insert(testPaper);
    }

    /**
     * 获取paper下边的所有试题
     *
     * @param paperId
     * @return
     */
    @Override
    public List<TopicEntity> getTopicsListByPaper(Integer paperId) {
        List<TopicEntity> topicList = new ArrayList<>();
        /**
         * 获取 paperInfo 数据
         */
        QueryWrapper<PaperInfo> pi = new QueryWrapper<>();
        pi.eq("paper_id", paperId);
        List<PaperInfo> paperInfoList = paperInfoDao.selectList(pi);
        if (paperInfoList == null || paperInfoList.size() == 0) {
            throw new RRException("试卷下没有试题,请联系管理员");
        }
        for (int i = 0; i < paperInfoList.size(); i++) {
            PaperInfo paperInfo = paperInfoList.get(i);
            TopicEntity topicEntity = topicDao.selectById(Integer.parseInt(paperInfo.getTopicId()));
            if (topicEntity != null) {
                QueryWrapper<OptionsEntity> qw1 = new QueryWrapper<>();
                qw1.eq("topic_id", topicEntity.getId());
                List<OptionsEntity> optionsList = optionsDao.selectList(qw1);
                topicEntity.setOptionsList(optionsList);
            }
            topicList.add(topicEntity);
        }
        return topicList;
    }

    /**
     * 从List中随机出count个对象(感觉性能很低)
     *
     * @param list
     * @param count
     * @return
     */
    public static List<TopicEntity> getRandomListData(List<TopicEntity> list, int count) {
        // 创建一个长度为count(count<=list)的数组,用于存随机数
        int[] a = new int[count];
        // 利于此数组产生随机数
        int[] b = new int[list.size()];
        int size = list.size();

        // 取样填充至数组a满
        for (int i = 0; i < count; i++) {
            int num = (int) (Math.random() * size); // [0,size)
            int where = -1;
            for (int j = 0; j < b.length; j++) {
                if (b[j] != -1) {
                    where++;
                    if (where == num) {
                        b[j] = -1;
                        a[i] = j;
                    }
                }
            }
            size = size - 1;
        }

        // a填满后 将数据加载到rslist
        List<TopicEntity> rslist = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            TopicEntity df = list.get(a[i]);
            rslist.add(df);
        }
        return rslist;
    }
}
